##KVC与KVO
###KVC(key-value-coding)键值编码
用来给一个对象的属性进行赋值或者访问.
通过类别的方式添加
@interface NSObject(NSKeyValueCoding)
使用:
- (void)setValue:(nullable id)value forKey:(NSString *)key;
- (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;
第二个方法通过路径的方式的访问,即可以访问成员变量是对象的属性 “Dog.age”
- (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;
应用:
- 系统Storyboard控件拖线
- 访问私有成员变量
- 字典转模型
字典转模型(属性名相同,不能是关键字,嵌套对象模型时还需另做处理,一般使用第三方)
- (void)setValuesForKeysWithDictionary:(NSDictionary
*)keyedValues;
遇到不能识别的key执行的方法 - (void)setValue:(nullable id)value forUndefinedKey:(NSString *)key;
原理:
###KVO(key-value-observing)键值监听
利用一个key来找到某个属性并监听其值的改变。典型的观察者模式
类别:@interface NSObject(NSKeyValueObserving)
使用:
- 添加监听
- 实现监听方法,observeValueForKeyPath: ofObject: change: context:
- 移除监听
相关API
- (void)addObserver:(NSObject )observer forKeyPath:(NSString )keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;//添加监听
- (void)removeObserver:(NSObject )observer forKeyPath:(NSString )keyPath context:(nullable void *)context API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0));//删除监听
- (void)removeObserver:(NSObject )observer forKeyPath:(NSString )keyPath;//删除监听
- (void)observeValueForKeyPath:(nullable NSString )keyPath ofObject:(nullable id)object change:(nullable NSDictionary<NSKeyValueChangeKey, id> )change context:(nullable void *)context;//监听实现方法
####手动实现KVO
重写该方法,对应的key但会NO
- (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key;
调用方法完成当值改变时发出通知
- (void)willChangeValueForKey:(NSString *)key;
- (void)didChangeValueForKey:(NSString *)key;
###KVO的实现原理
当一个类的属性被观察的时候,系统会通过runtime动态的创建一个该类的派生类,并且会在这个类中重写基类被观察的属性的setter方法,而且系统将这个类的isa指针指向了派生类,从而实现了给监听的属性赋值时调用的是派生类的setter方法。重写的setter方法会在调用原setter方法前后,通知观察对象值得改变。